package com.xbongbong.saas.help;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.ext.PaasAttachmentEntityExt;
import com.xbongbong.paas.enums.ComboTypeEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.ItemPoJo;
import com.xbongbong.paas.field.SubFormPoJo;
import com.xbongbong.paas.help.FormDataHelp;
import com.xbongbong.paas.help.ProFormHelp;
import com.xbongbong.paas.pojo.dto.AnalysisDataDTO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.JsonHelperUtil;
import com.xbongbong.paas.toolbox.util.RegexUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.util.TelephoneMaskUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.paas.util.ItemUtil;
import com.xbongbong.pro.enums.AmountFlagEnum;
import com.xbongbong.pro.enums.PaasStageEnum;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ProductConstant;
import com.xbongbong.saas.domain.entity.competitor.CompetitorEntity;
import com.xbongbong.saas.enums.SelectProductEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.AssembleEnum;
import com.xbongbong.saas.enums.business.CompetitorEnum;
import com.xbongbong.saas.enums.business.ContactEnum;
import com.xbongbong.saas.enums.business.InventoryEnum;
import com.xbongbong.saas.enums.business.OutstockEnum;
import com.xbongbong.saas.enums.business.ProductEnum;
import com.xbongbong.saas.enums.business.ReceiptOrderEnum;
import com.xbongbong.saas.enums.business.SalesOpportunityEnum;
import com.xbongbong.saas.enums.business.ServiceProjectEnum;
import com.xbongbong.saas.enums.business.TransferEnum;
import com.xbongbong.saas.model.CompetitorModel;
import com.xbongbong.saas.model.DistributorAreaModel;
import com.xbongbong.saas.service.toolbox.help.AttrDecimalPrecisionHelper;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

@Component
public class FormDataAnalysisHelp {

    @Resource
    private RelativeProductHelp relativeProductHelp;
    @Resource
    private SaasFormHelp saasFormHelp;
    @Resource
    private ProFormHelp proFormHelp;
    @Resource
    private FormDataHelp formDataHelp;
    @Resource
    private CompetitorModel competitorModel;

    /**
     * 列表和详情解析下拉
     * @param jsonObject 目标jsonObject
     * @param resultJsonObject 结果jsonObject
     * @param corpid
     */
    public void  analysisCombo(JSONObject jsonObject, JSONObject resultJsonObject, FieldAttrEntity fieldAttrEntity, String corpid) throws XbbException {
        String attr = fieldAttrEntity.getAttr();
        if (Objects.equals(fieldAttrEntity.getSaasAttr(), SelectProductEnum.UNIT.getSaasAttr())) {
            List<ItemPoJo> productItems = relativeProductHelp.getBusinessUnitItems(corpid);
            fieldAttrEntity.setItems(productItems);
        }else if (Objects.equals(fieldAttrEntity.getSaasAttr(), ProductEnum.UNIT.getSaasAttr())){
            List<ItemPoJo> productItems = saasFormHelp.getProductItems(corpid);
            fieldAttrEntity.setItems(productItems);
        } else if (Objects.equals(fieldAttrEntity.getSaasAttr(), ServiceProjectEnum.UNIT.getSaasAttr())){
            List<ItemPoJo> productItems = saasFormHelp.getProductItems(corpid);
            fieldAttrEntity.setItems(productItems);
        }
        if (Objects.equals(fieldAttrEntity.getComboType(), ComboTypeEnum.CUSTOM.getType())) {
            Object itemValue = ItemUtil.getCustomItemList(fieldAttrEntity, jsonObject);
            resultJsonObject.put(attr, itemValue);
        } else if (Objects.equals(fieldAttrEntity.getComboType(), ComboTypeEnum.DATARELY.getType()) ||
                Objects.equals(fieldAttrEntity.getComboType(), ComboTypeEnum.LINKFORM.getType())||
                Objects.equals(fieldAttrEntity.getComboType(), ComboTypeEnum.BUSINESS.getType())) {
            List<ItemPoJo> itemPoJos = fieldAttrEntity.getItems();
            Map<Object, ItemPoJo> itemMap = new HashMap<>(itemPoJos.size());
            Set<String> textSet = new HashSet<>();
            itemPoJos.forEach(item->{
                itemMap.put(item.getValue(), item);
                textSet.add(item.getText());
            });
            if (Objects.nonNull(jsonObject.get(attr))) {
                if (jsonObject.get(attr) instanceof List) {
                    JSONArray jsonArray = jsonObject.getJSONArray(attr);
                    for (Object object: jsonArray) {
                        String value = object.toString();
                        if (itemMap.containsKey(value)) {
                            Object itemValue = ItemUtil.getCustomItemList(fieldAttrEntity, jsonObject);
                            resultJsonObject.put(attr, itemValue);
                            return;
                        } else if (ItemUtil.isUUID(value) && !textSet.contains(value)) {
                            // 是uuid并且文本中没有这种数据
                            resultJsonObject.put(attr, null);
                        } else {
                            resultJsonObject.put(attr, jsonObject.get(attr));
                        }
                    }
                }else if (itemMap.containsKey(jsonObject.get(attr))) {
                    Object itemValue = ItemUtil.getCustomItemList(fieldAttrEntity, jsonObject);
                    resultJsonObject.put(attr, itemValue);
                } else {
                    resultJsonObject.put(attr, jsonObject.get(attr));
                }
            }
        }
    }

    /**
     * 列表和详情解析下拉(带颜色)
     *
     * @param jsonObject       目标jsonObject
     * @param resultJsonObject 结果jsonObject
     * @param fieldAttrEntity 表单字段属性
     * @param corpid 公司Id
     */
    public void analysisComboWithColor(JSONObject jsonObject, JSONObject resultJsonObject, FieldAttrEntity fieldAttrEntity, String corpid) throws XbbException {
        String attr = fieldAttrEntity.getAttr();
        if (Objects.equals(fieldAttrEntity.getSaasAttr(), SelectProductEnum.UNIT.getSaasAttr())) {
            List<ItemPoJo> productItems = relativeProductHelp.getBusinessUnitItems(corpid);
            fieldAttrEntity.setItems(productItems);
        } else if (Objects.equals(fieldAttrEntity.getSaasAttr(), ProductEnum.UNIT.getSaasAttr())) {
            List<ItemPoJo> productItems = saasFormHelp.getProductItems(corpid);
            fieldAttrEntity.setItems(productItems);
        } else if (Objects.equals(fieldAttrEntity.getSaasAttr(), ServiceProjectEnum.UNIT.getSaasAttr())) {
            List<ItemPoJo> productItems = saasFormHelp.getServiceItems(corpid);
            fieldAttrEntity.setItems(productItems);
        }
        if (Objects.equals(fieldAttrEntity.getComboType(), ComboTypeEnum.CUSTOM.getType())) {
            Object commonItem = ItemUtil.getCommonItem(fieldAttrEntity, jsonObject);
            resultJsonObject.put(attr, commonItem);
        } else if (Objects.equals(fieldAttrEntity.getComboType(), ComboTypeEnum.DATARELY.getType()) ||
                Objects.equals(fieldAttrEntity.getComboType(), ComboTypeEnum.LINKFORM.getType()) ||
                Objects.equals(fieldAttrEntity.getComboType(), ComboTypeEnum.BUSINESS.getType())) {
            List<ItemPoJo> itemPoJos = fieldAttrEntity.getItems();
            Map<Object, ItemPoJo> itemMap = new HashMap<>(itemPoJos.size());
            Set<String> textSet = new HashSet<>();
            itemPoJos.forEach(item -> {
                itemMap.put(item.getValue(), item);
                textSet.add(item.getText());
            });
            if (Objects.nonNull(jsonObject.get(attr))) {
                if (jsonObject.get(attr) instanceof List) {
                    // 多选
                    JSONArray jsonArray = jsonObject.getJSONArray(attr);
                    for (Object object : jsonArray) {
                        String value = object.toString();
                        if (ItemUtil.isUUID(value) && !textSet.contains(value)) {
                            // 是uuid并且文本中没有这种数据
                            resultJsonObject.put(attr, null);
                        } else if (!ItemUtil.isUUID(value) || itemMap.containsKey(value)) {
                            Object itemValue = ItemUtil.getCommonItem(fieldAttrEntity, jsonObject);
                            resultJsonObject.put(attr, itemValue);
                            return;
                        } else {
                            String valueStr = jsonObject.get(attr).toString();
                            resultJsonObject.put(attr, new ItemPoJo(valueStr, valueStr, false, ""));
                            return;
                        }
                    }
                } else if (itemMap.containsKey(jsonObject.get(attr))) {
                    // 单选按钮或者下拉框，在自定义选项中
                    Object itemValue = ItemUtil.getCommonItem(fieldAttrEntity, jsonObject);
                    resultJsonObject.put(attr, itemValue);
                } else {
                    // 单选按钮或者下拉框，不在自定义选项中
                    Object itemValue = ItemUtil.getCommonItem(fieldAttrEntity, jsonObject);
                    resultJsonObject.put(attr, itemValue);
                }
            }
        }
    }

    /**
     * 编辑时解析下拉
     * @param jsonObject 目标jsonObject
     * @param resultJsonObject 结果jsonObject
     *                         单选的格式为：{"text": "", "value": ""}
     *                         多选的格式为：[{"text": "", "value": ""}]
     */
    public void analysisComboJsonObject(JSONObject jsonObject, JSONObject resultJsonObject, FieldAttrEntity fieldAttrEntity){
        String attr = fieldAttrEntity.getAttr();
        List<ItemPoJo> itemPoJos = fieldAttrEntity.getItems();
        Map<Object, ItemPoJo> itemMap = new HashMap<>(itemPoJos.size());
        Set<String> textSet = new HashSet<>();
        itemPoJos.forEach(item->{
            itemMap.put(item.getValue(), item);
            textSet.add(item.getText());
        });
        if (Objects.equals(fieldAttrEntity.getComboType(), ComboTypeEnum.CUSTOM.getType())) {
            Object itemValue = jsonObject.get(attr);
            // 这里有可能有数组类型的字符串数据，还是加一个字段类型的判断吧。
            if (itemValue instanceof ArrayList || itemValue instanceof JSONArray
                    || Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.CHECKBOX_GROUP.getType())) {
                JSONArray list = jsonObject.getJSONArray(attr);
                if (Objects.isNull(list)) {
                    list = new JSONArray();
                }
                if (!list.isEmpty()) {
                    itemValue = setListValue(list, itemMap);
                } else {
                    itemValue = new ArrayList<>();
                }
                resultJsonObject.put(attr, itemValue);
            } else if (itemValue instanceof String && Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.COMBO_CHECK.getType())) {
                // 工作日报特殊逻辑
                resultJsonObject.put(attr, itemValue);
            } else if (Objects.equals(fieldAttrEntity.getSaasAttr(), ProductEnum.UNIT.getSaasAttr()) && Objects.nonNull(fieldAttrEntity.getMultiItems()) && (jsonObject.get(attr) instanceof Number && jsonObject.getLong(attr) > ProductConstant.MAX_SINGLE_UNIT_VALUE)) {
                // 产品多单位特殊逻辑
                itemValue = ItemUtil.getUnitItemList(fieldAttrEntity, jsonObject);
                if (Objects.isNull(itemValue) || StringUtil.isEmpty(itemValue.toString())) {
                    resultJsonObject.put(attr, null);
                } else {
                    resultJsonObject.put(attr, setValue(jsonObject.get(attr), itemValue));
                }
            } else  {
                itemValue = ItemUtil.getCustomItemList(fieldAttrEntity, jsonObject);
                if (Objects.isNull(itemValue) || StringUtil.isEmpty(itemValue.toString(), false)) {
                    resultJsonObject.put(attr, null);
                } else {
                    resultJsonObject.put(attr, setValue(jsonObject.get(attr), itemValue));
                }
            }
        } else if (Objects.equals(fieldAttrEntity.getComboType(), ComboTypeEnum.DATARELY.getType()) ||
                Objects.equals(fieldAttrEntity.getComboType(), ComboTypeEnum.LINKFORM.getType()) ||
                Objects.equals(fieldAttrEntity.getComboType(), ComboTypeEnum.BUSINESS.getType())) {
            if (Objects.nonNull(jsonObject.get(attr))) {
                if (Objects.equals(FieldTypeEnum.COMBO.getType(), fieldAttrEntity.getFieldType())
                        || Objects.equals(FieldTypeEnum.RADIO_GROUP.getType(), fieldAttrEntity.getFieldType())) {
                    String key = fieldAttrEntity.getAttr();
                    Object itemValue = jsonObject.get(key);
                    if (itemMap.containsKey(itemValue)) {
                        resultJsonObject.put(attr, setValue(itemValue, itemMap.get(itemValue).getText()));
                    } else {
                        resultJsonObject.put(attr, setValue(itemValue, itemValue));
                    }
                } else if (Objects.nonNull(jsonObject.get(attr))) {
                    if (jsonObject.get(attr) instanceof ArrayList || jsonObject.get(attr) instanceof JSONArray) {
                        JSONArray jsonArray = jsonObject.getJSONArray(attr);
                        List<JSONObject> value = new ArrayList<>();
                        for (Object item : jsonArray) {
                            if (itemMap.containsKey(item)) {
                                value.add(setValue(item, itemMap.get(item).getText()));
                            } else if (ItemUtil.isUUID(item.toString()) && !textSet.contains(item)) {
                                continue;
                            } else {
                                value.add(setValue(item, item));
                            }
                        }
                        resultJsonObject.put(attr, value);
                    } else {
                        if (itemMap.containsKey(jsonObject.get(attr))) {
                            resultJsonObject.put(attr, setValue(jsonObject.get(attr), itemMap.get(jsonObject.get(attr)).getText()));
                        } else {
                            resultJsonObject.put(attr, setValue(jsonObject.get(attr), jsonObject.get(attr)));
                        }
                    }

                }
            }
        }
    }

    /**
     * 设置下拉框复选和多选的值
     * @param list
     * @param itemMap
     * @return [{"text": "", "value": ""}]
     */
    private List<Object> setListValue(JSONArray list, Map<Object, ItemPoJo> itemMap) {
        List<Object> valueList = new ArrayList<>();
        for(Object value: list) {
            ItemPoJo itemPoJo = itemMap.get(value);
            if (Objects.nonNull(itemPoJo)) {
                valueList.add(setValue(itemPoJo.getValue(), itemPoJo.getText()));
            } else if (Objects.nonNull(value) && !ItemUtil.isUUID(value.toString()) && !RegexUtil.isOnePositiveInt(value.toString())) {
                // 如果是uuId，则应该是已经被删了的下拉框
                valueList.add(setValue(value, value));
            }
        }
        return valueList;
    }

    /**
     * 设置下拉框单选选和单选的值
     * @param value 存储的值
     * @param text 显示的值
     * @return {"text": "", "value": ""}
     */
    private JSONObject setValue(Object value, Object text) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("value", value);
        jsonObject.put("text", text);
        return jsonObject;
    }

    private JSONObject setValue(Object value, Object text, Object stageId, Object stageProcessId, Object stageRatio, String color) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("value", value);
        jsonObject.put("text", text);
        jsonObject.put(PaasStageEnum.STAGE_ID.getSaasAttr(), stageId);
        jsonObject.put(PaasStageEnum.STAGE_PROCESS_ID.getSaasAttr(), stageProcessId);
        jsonObject.put(PaasStageEnum.STAGE_RATIO.getSaasAttr(), stageRatio);
        jsonObject.put("color", color);
        return jsonObject;
    }

    public void analysisComboReturnList(JSONObject jsonObject, JSONObject resultJsonObject, FieldAttrEntity fieldAttrEntity) {
        resultJsonObject.put(fieldAttrEntity.getAttr(), ItemUtil.analysisComboReturnList(jsonObject, fieldAttrEntity));
    }

    /**
     * 解析数组
     * @param jsonObject 目标jsonObject
     * @param resultJsonObject 结果jsonObject
     */
    public void analysisComboReturnStr(JSONObject jsonObject, JSONObject resultJsonObject, FieldAttrEntity fieldAttrEntity){
        resultJsonObject.put(fieldAttrEntity.getAttr(), ItemUtil.analysisComboReturnStr(jsonObject, fieldAttrEntity));
    }

    /**
     * 解析数组(带颜色)
     * @param jsonObject 目标jsonObject
     * @param resultJsonObject 结果jsonObject
     */
    public void analysisComboReturnStrWithColor(JSONObject jsonObject, JSONObject resultJsonObject, FieldAttrEntity fieldAttrEntity){
        resultJsonObject.put(fieldAttrEntity.getAttr(), ItemUtil.analysisComboReturnStrWithColor(jsonObject, fieldAttrEntity));
    }

    /**
     * 解析附件
     * @param value
     * @return
     */
    public List<PaasAttachmentEntityExt> analysisAttachmentList(String value){
        return JsonHelperUtil.parseArray(value, PaasAttachmentEntityExt.class);
    }

    /**
     * 列表中，数据不可见时，将其设置成null，则列表中数据就不会显示
     * @param fieldAttrEntity
     * @param analysisDataDTO
     * @param objectJsonObject
     * @return true:隐藏；false：不隐藏
     */
    public static boolean invisibleSetNull(FieldAttrEntity fieldAttrEntity, AnalysisDataDTO analysisDataDTO, JSONObject objectJsonObject) throws XbbException {
        boolean invisibleOfScope = false;
        Integer visibleScopeEnable = fieldAttrEntity.getVisibleScopeEnable();
        // 高级可见规则回显用户名称
        if (Objects.equals(visibleScopeEnable, 1)) {
            String key = fieldAttrEntity.getAttr();
            HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
            BeanUtil.copyProperties(analysisDataDTO, handlerExplainDTO);

            if (ExplainUtil.invisibleOfScope(fieldAttrEntity, handlerExplainDTO)) {
                objectJsonObject.put(key, null);
                invisibleOfScope = true;
            }
        }
        return invisibleOfScope;
    }

    /**
     * saas之解析数据
     * @param analysisDataDTO
     * @param key
     * @param objectJsonObject
     * @param resultJsonObject
     */
    public void saasAnalysisData(AnalysisDataDTO analysisDataDTO, String key, JSONObject objectJsonObject, JSONObject resultJsonObject) {
        // saas关联业务的特殊逻辑
        // TODO 拆分
        Integer businessType = analysisDataDTO.getBusinessType();
        Integer saasMark = analysisDataDTO.getSaasMark();
        if (Objects.equals(saasMark, 1)) {
            resultJsonObject.put(key, objectJsonObject.get(key));
            if (Objects.equals(businessType, XbbRefTypeEnum.OUTSTOCK.getCode())) {
                if (Objects.equals(key, OutstockEnum.WAREHOUSE_ID.getAttr())) {
                    String linkAttr = OutstockEnum.WAREHOUSE_ID_LINKED_TEXT.getAttr();
                    resultJsonObject.put(linkAttr, objectJsonObject.get(linkAttr));
                }
                if (Objects.equals(key, OutstockEnum.REF_ID.getAttr())) {
                    String linkAttr = OutstockEnum.REF_ID_LINKED_TEXT.getAttr();
                    resultJsonObject.put(linkAttr, objectJsonObject.get(linkAttr));
                }
            } else if (Objects.equals(businessType, XbbRefTypeEnum.CONTACT.getCode())) {
                if (Objects.equals(key, ContactEnum.CUSTOMER_NAME.getAttr())) {
                    String linkAttr = ContactEnum.CUSTOMER_NAME_LINK_TEXT.getAttr();
                    resultJsonObject.put(linkAttr, objectJsonObject.get(linkAttr));
                }
            } else if (Objects.equals(businessType, XbbRefTypeEnum.INVENTORY.getCode())) {
                if (Objects.equals(key, InventoryEnum.WAREHOUSE_ID.getAttr())) {
                    String linkAttr = InventoryEnum.WAREHOUSE_ID_LINKED_TEXT.getAttr();
                    resultJsonObject.put(linkAttr, objectJsonObject.get(linkAttr));
                }
            } else if (Objects.equals(businessType, XbbRefTypeEnum.TRANSFER.getCode())) {
                if (Objects.equals(key, TransferEnum.OUT_WAREHOUSE_ID.getAttr())) {
                    String linkAttr = TransferEnum.OUT_WAREHOUSE_ID_LINKED_TEXT.getAttr();
                    resultJsonObject.put(linkAttr, objectJsonObject.get(linkAttr));
                }
                if (Objects.equals(key, TransferEnum.INTO_WAREHOUSE_ID.getAttr())) {
                    String linkAttr = TransferEnum.INTO_WAREHOUSE_ID_LINKED_TEXT.getAttr();
                    resultJsonObject.put(linkAttr, objectJsonObject.get(linkAttr));
                }
            } else if (Objects.equals(businessType, XbbRefTypeEnum.ASSEMBLE.getCode())) {
                if (Objects.equals(key, AssembleEnum.OUT_WAREHOUSE_ID.getAttr())) {
                    String linkAttr = AssembleEnum.OUT_WAREHOUSE_ID_LINKED_TEXT.getAttr();
                    resultJsonObject.put(linkAttr, objectJsonObject.get(linkAttr));
                }
                if (Objects.equals(key, AssembleEnum.INTO_WAREHOUSE_ID.getAttr())) {
                    String linkAttr = AssembleEnum.INTO_WAREHOUSE_ID_LINKED_TEXT.getAttr();
                    resultJsonObject.put(linkAttr, objectJsonObject.get(linkAttr));
                }
            }
        }
    }

    @SuppressWarnings("unchecked")
    public void analysisAmountOfThousandBitsNomal(JSONObject resultJson,String attr,Map<String,Object> explainMap,Boolean analysisAmountOfThousandBitsWithOriginalValue){
        if(explainMap.containsKey(attr)) {
            Object object = explainMap.get(attr);
            Object originalValve = resultJson.get(attr);
            if (Objects.isNull(originalValve)) {
                return;
            }
            FieldAttrEntity fieldAttrEntity = null;
            Map<String,FieldAttrEntity> fieldAttrMap = null;
            if(object instanceof FieldAttrEntity){
                fieldAttrEntity = (FieldAttrEntity) object;
            }
            if(object instanceof Map){
                fieldAttrMap = (Map<String,FieldAttrEntity>) object;
            }
            if (Objects.nonNull(fieldAttrEntity)) {
                if (Objects.equals(analysisAmountOfThousandBitsWithOriginalValue, true)) {
                    originalValveAssemble(fieldAttrEntity,originalValve,resultJson,attr);
                } else {
                    unOriginalValveAssemble(fieldAttrEntity,originalValve,resultJson,attr);
                }
            }else if(null != fieldAttrMap) {
                //子表单的千份位解析特殊处理,先解析值，取得对应的key取fieldAttrEntity
                List<JSONObject> params = JSONArray.parseObject(originalValve.toString(), new TypeReference<List<JSONObject>>(){});
                List<JSONObject> newJsonList = new ArrayList();
                for (JSONObject jsonObject : params) {
                    Iterator<Map.Entry<String, Object>> it = jsonObject.entrySet().iterator();
                    while (it.hasNext()) {
                        Map.Entry<String, Object> entry = it.next();
                        String key = entry.getKey();
                        Object value = entry.getValue();
                        if (fieldAttrMap.containsKey(key)) {
                            FieldAttrEntity subFieldAttrEntity = fieldAttrMap.get(key);
                            if (Objects.equals(analysisAmountOfThousandBitsWithOriginalValue, true)) {
                                originalValveAssemble(subFieldAttrEntity,value,jsonObject,key);
                            } else {
                                unOriginalValveAssemble(subFieldAttrEntity,value,jsonObject,key);
                            }
                        }
                    }
                    newJsonList.add(jsonObject);
                }
                //子表单直接覆盖修改原来的值
                resultJson.put(attr, newJsonList);
            }
        }
    }

    private void originalValveAssemble(FieldAttrEntity fieldAttrEntity,Object originalValve,JSONObject resultJson,String attr){
        Integer accuracy = fieldAttrEntity.getAccuracy();
        if (Objects.equals(fieldAttrEntity.getIntegerOnly(), 1)) {
            // 当其为整数
            accuracy = 0;
        }
        Object thousandthValve = AttrDecimalPrecisionHelper.parseThousandth(originalValve, accuracy);
        JSONObject amountObj = new JSONObject();
        amountObj.put("originalValve", originalValve);
        amountObj.put("thousandthValve", thousandthValve);
        resultJson.put(attr, amountObj);
    }

    private void unOriginalValveAssemble(FieldAttrEntity fieldAttrEntity,Object originalValve,JSONObject resultJson,String attr){
        Integer accuracy = fieldAttrEntity.getAccuracy();
        if (Objects.equals(fieldAttrEntity.getIntegerOnly(), 1)) {
            // 当其为整数
            accuracy = 0;
        }
        resultJson.put(attr, AttrDecimalPrecisionHelper.parseThousandth(originalValve,accuracy));
    }

    /**
     * 将需要解析的金额字段放入map
     * @param fieldAttrEntityList
     * @param explainMap
     */
    public static Map<String,Object> needAnalysisFieldAttr(List<FieldAttrEntity> fieldAttrEntityList){
        Map<String,Object> explainMap = new HashMap<>(fieldAttrEntityList.size());
        for(FieldAttrEntity fieldAttrEntity : fieldAttrEntityList){
            if(Objects.equals(fieldAttrEntity.getFieldType(),FieldTypeEnum.NUM.getType())){
                if(Objects.equals(fieldAttrEntity.getAmountFlag(), AmountFlagEnum.YES.getType())){
                    explainMap.put(fieldAttrEntity.getAttr(), fieldAttrEntity);
                }
            }else if(Objects.equals(fieldAttrEntity.getFieldType(),FieldTypeEnum.SUB_FORM.getType())){
                //先排除掉没有金额数字字段的子表单
                SubFormPoJo subFormPoJo = fieldAttrEntity.getSubForm();
                List<? extends FieldAttrEntity> jsonArray = subFormPoJo.getItems();
                Map<String,FieldAttrEntity> subFormAttrMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                for(int i=0;i<jsonArray.size();i++){
                    FieldAttrEntity fieldAttr = jsonArray.get(i);
                    if(Objects.equals(fieldAttr.getFieldType(),FieldTypeEnum.NUM.getType())){
                        if(Objects.equals(fieldAttr.getAmountFlag(), AmountFlagEnum.YES.getType())){
                            subFormAttrMap.put(fieldAttr.getAttr(),fieldAttr);
                            explainMap.put(fieldAttrEntity.getAttr(), subFormAttrMap);
                        }
                    }
                }
            }
        }
        return explainMap;
    }

    public static Map<Long, Map<String, Object>> needAnalysisFieldAttr(Map<Long, List<FieldAttrEntity>> explainListMap){
        Map<Long, Map<String, Object>> explainMap = new HashMap<>(explainListMap.size());
        explainListMap.forEach((key, value)->{
            explainMap.put(key, needAnalysisFieldAttr(value));
        });
        return explainMap;
    }
    /**
     * @Author sunshaoxiang
     * @Description 解析阶段字段
     * @param jsonObject
     * @param resultJsonObject
     * @param fieldAttrEntity
     **/
    public void analysisStageJsonObject(AnalysisDataDTO analysisDataDTO, JSONObject jsonObject, JSONObject resultJsonObject, FieldAttrEntity fieldAttrEntity) throws XbbException {
        String attr = fieldAttrEntity.getAttr();
        Integer saasMark = analysisDataDTO.getSaasMark();
        Integer businessType = analysisDataDTO.getBusinessType();
        String corpid = analysisDataDTO.getCorpid();
        Long formId = analysisDataDTO.getFormId();
        //列表页也会调这边的方法，所以实时拿一下
        List<ItemPoJo> itemPoJos = proFormHelp.getEditStageComboItems(fieldAttrEntity, saasMark, businessType, corpid, formId, jsonObject);
        Map<Object, ItemPoJo> itemMap = new HashMap<>(itemPoJos.size());
        //拿阶段code
        String code = jsonObject.getString(attr);
        itemPoJos.forEach(item->{
            itemMap.put(item.getValue(), item);
        });
        //只有阶段值不为空，才会将相关参数封装进去
        if (StringUtil.isNotEmpty(code)) {
            if (itemMap.containsKey(code)) {
                Long stageProcessId = FastJsonHelper.getLongOrDefaultFromFormData(jsonObject, PaasStageEnum.STAGE_PROCESS_ID.getAttr(), BasicConstant.ZERO_LONG);
                //如果没有stageProcessId, 说明是迁移版本，从解释里面拿
                if (Objects.equals(stageProcessId, BasicConstant.ZERO_LONG)) {
                    resultJsonObject.put(attr, setValue(code, itemMap.get(code).getText(), itemMap.get(code).getStageId(),
                            itemMap.get(code).getStageProcessId(),itemMap.get(code).getStageRatio(), itemMap.get(code).getColor()));
                } else {
                    Long stageId = FastJsonHelper.getLongOrDefaultFromFormData(jsonObject, PaasStageEnum.STAGE_ID.getAttr(), BasicConstant.ZERO_LONG);
                    Integer stageRadio = FastJsonHelper.getIntegerOrDefaultFromFormData(jsonObject, PaasStageEnum.STAGE_RATIO.getAttr(), BasicConstant.ZERO);
                    resultJsonObject.put(attr, setValue(code, itemMap.get(code).getText(), stageId, stageProcessId, stageRadio, itemMap.get(code).getColor()));
                }
            } else {
                //如果出现了异常的阶段code,不应该抛异常，直接置空
                resultJsonObject.put(attr, null);
            }
        }
    }

    /**
     * @Author sunshaoxiang
     * @Description 解析详情列表页等场景下阶段推进器字段
     * @param resultJsonObject
     * @param analysisDataDTO
     */
    public void analysisListStageJsonObject(JSONObject resultJsonObject, AnalysisDataDTO analysisDataDTO) throws XbbException {
        FieldAttrEntity fieldAttrEntity = analysisDataDTO.getFieldAttrEntity();
        Integer saasMark = analysisDataDTO.getSaasMark();
        Integer businessType = analysisDataDTO.getBusinessType();
        JSONObject jsonObject = analysisDataDTO.getDataJsonObject();
        String corpid = analysisDataDTO.getCorpid();
        String attr = fieldAttrEntity.getAttr();
        String value = getStageValue(corpid, fieldAttrEntity, jsonObject, analysisDataDTO.getFormId(), businessType, saasMark);
        resultJsonObject.put(attr, value);
    }

    /**
     * @Author sunshaoxiang
     * @Description 解析详情列表页等场景下阶段推进器字段
     * @param resultJsonObject
     * @param analysisDataDTO
     */
    public void analysisListStageJsonObjectWithColor(JSONObject resultJsonObject, AnalysisDataDTO analysisDataDTO) throws XbbException {
        FieldAttrEntity fieldAttrEntity = analysisDataDTO.getFieldAttrEntity();
        Integer saasMark = analysisDataDTO.getSaasMark();
        Integer businessType = analysisDataDTO.getBusinessType();
        JSONObject jsonObject = analysisDataDTO.getDataJsonObject();
        String corpid = analysisDataDTO.getCorpid();
        String attr = fieldAttrEntity.getAttr();
        String value = getStageValue(corpid, fieldAttrEntity, jsonObject, analysisDataDTO.getFormId(), businessType, saasMark);
        Map<String, String> colorMap = new HashMap<>();
        fieldAttrEntity.getItems().forEach(item -> colorMap.put(item.getText(), item.getColor()));
        resultJsonObject.put(attr, StringUtil.isEmpty(value) ? null : new ItemPoJo(value, value, false, colorMap.get(value)));
    }

    /**
     * 阶段code对应的value值
     * @param corpid
     * @param fieldAttrEntity
     * @param data
     * @param formId
     * @param businessType
     * @param saasMark
     * @return
     * @throws XbbException
     */
    public String getStageValue(String corpid, FieldAttrEntity fieldAttrEntity, JSONObject data, Long formId, Integer businessType, Integer saasMark) throws XbbException {
        if (Objects.isNull(fieldAttrEntity)) {
            return null;
        }
        String attr = fieldAttrEntity.getAttr();
        List<ItemPoJo> itemPoJos = proFormHelp.getEditStageComboItems(fieldAttrEntity, saasMark, businessType, corpid, formId, data);
        Map<Object, ItemPoJo> itemMap = new HashMap<>(itemPoJos.size());
        Object itemValue = data.get(attr);
        itemPoJos.forEach(item->{
            itemMap.put(item.getValue(), item);
        });
        if (itemMap.containsKey(itemValue)) {
           return itemMap.get(itemValue).getText();
        } else {
            return null;
        }
    }


    /**
     * 解析阶段停留时长字段
     * @param resultJsonObject
     * @param attr
     */
    public void analysisStageStayTime(JSONObject resultJsonObject, String attr) {
        Long intoStageTime = resultJsonObject.getLong(attr);
        if (Objects.isNull(intoStageTime)) {
            resultJsonObject.put(attr, null);
        } else {
           float stageStayTime = DateTimeUtil.getTimeDifferenceByDay(DateTimeUtil.getInt(), intoStageTime);
           resultJsonObject.put(attr, stageStayTime + "天");
        }
    }

    /**
     * 解析电话字段，如果开启了电话掩码配置，则对电话号码进行掩码处理
     * @param fieldAttrEntity
     * @param objectJsonObject
     * @param resultJsonObject
     * @param loginUser
     */
    public void analysisTelephoneNumber(FieldAttrEntity fieldAttrEntity, JSONObject objectJsonObject, JSONObject resultJsonObject, UserVO loginUser) {
        Integer isMaskTelephone = fieldAttrEntity.getIsMaskTelephone();
        String attr = fieldAttrEntity.getAttr();
        String telephoneNumber = objectJsonObject.getString(fieldAttrEntity.getAttr());
        //管理员和老板不受电话掩码设置影响
        if (Objects.isNull(loginUser) || loginUser.isAdminOrBoss()) {
            resultJsonObject.put(attr, telephoneNumber);
            return;
        }
        if (StringUtil.isNotEmpty(telephoneNumber) && Objects.equals(isMaskTelephone, BasicConstant.ONE)) {
            //掩码处理后的电话号码
            String maskTelephoneCode = TelephoneMaskUtil.maskTelephone(telephoneNumber);
            resultJsonObject.put(attr, maskTelephoneCode);
        } else {
            resultJsonObject.put(attr, telephoneNumber);
        }
    }

    /**
     * 导出时解析电话字段，如果开启了电话掩码配置，则对电话号码进行掩码处理
     *
     * @param fieldAttrEntity       电话字段
     * @param phoneFieldAttrEntity  电话的值字段
     * @param formData              表单数据
     * @param loginUser             登录用户
     */
    public void analysisTelephoneNumber4Export(FieldAttrEntity fieldAttrEntity, FieldAttrEntity phoneFieldAttrEntity,JSONObject formData, UserVO loginUser) {
        // 管理员和老板不受电话掩码设置影响
        if (Objects.isNull(loginUser) || loginUser.isAdminOrBoss()) {
            return;
        }

        Integer isMaskTelephone = phoneFieldAttrEntity.getIsMaskTelephone();
        String attr = fieldAttrEntity.getAttr();
        String phoneAttr = phoneFieldAttrEntity.getAttr();

        JSONArray phoneArray = FastJsonHelper.getJsonArrayOrDefault(formData, attr, new JSONArray());
        // 没有开启掩码功能时不用处理
        if (CollectionsUtil.isEmpty(phoneArray) || !Objects.equals(isMaskTelephone, BasicConstant.ONE)) {
            return;
        }

        for (int i=0; i<phoneArray.size(); i++) {
            JSONObject phoneObj = phoneArray.getJSONObject(i);
            String telephoneNumber = phoneObj.getString(phoneAttr);
            if (StringUtil.isEmpty(telephoneNumber)) {
                continue;
            }
            //掩码处理后的电话号码
            String maskTelephoneCode = TelephoneMaskUtil.maskTelephone(telephoneNumber);
            phoneObj.put(phoneAttr, maskTelephoneCode);
        }
        formData.put(attr, phoneArray);
    }

    /**
     * 解析赢单竞争对手
     * date: 2022/8/25 4:02 下午
     * @author yingjf
     * @param analysisDataDTO:
     * @param objectJsonObject:
     * @param resultJsonObject:
     * @param key:
     */
    public void analysisWinCompetior(AnalysisDataDTO analysisDataDTO,JSONObject objectJsonObject,JSONObject resultJsonObject,String key){
        String corpid = analysisDataDTO.getCorpid();
        Object object = objectJsonObject.get(SalesOpportunityEnum.WIN_COMPETITOR.getAttr());
        if(object!=null){
            long id = Long.parseLong(object.toString());
            CompetitorEntity competitorEntity = competitorModel.getByKey(id, corpid);
            String name = competitorEntity.getData().getString(CompetitorEnum.NAME.getAttr());
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("id",id);
            jsonObject.put("name",name);
            jsonObject.put("businessType",XbbRefTypeEnum.COMPETITOR.getCode());
            JSONArray jsonArray = new JSONArray();
            jsonArray.add(jsonObject);
            resultJsonObject.put(key,jsonArray);
        }
    }

    public void analysisLinkCompetior(AnalysisDataDTO analysisDataDTO,JSONObject objectJsonObject,JSONObject resultJsonObject,String key){
        String corpid = analysisDataDTO.getCorpid();
        JSONArray jsonArray = objectJsonObject.getJSONArray(SalesOpportunityEnum.LINK_COMPETITOR.getAttr());
        if(jsonArray!=null){
            Set<Long> idSet = new HashSet<>();
            for(Object item:jsonArray){
                long id = Long.parseLong(item.toString());
                idSet.add(id);
            }
            List<CompetitorEntity> competitorEntityList = competitorModel.getByKeys(idSet, corpid);
            Map<Long,String> nameMap =  new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            competitorEntityList.forEach(item->{
                nameMap.put(item.getId(),item.getData().getString(CompetitorEnum.NAME.getAttr()));
            });
            JSONArray nameArray = new JSONArray();
            for(Object item:jsonArray){
                long id = Long.parseLong(item.toString());
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("id",id);
                jsonObject.put("name",nameMap.get(id));
                jsonObject.put("businessType",XbbRefTypeEnum.COMPETITOR.getCode());
                nameArray.add(jsonObject);
            }
            resultJsonObject.put(key,nameArray);
        }
    }

    /**
     *  关联数据多选特殊解析
     * date: 2022/8/25 6:41 下午
     * @author yingjf
     * @param analysisDataDTO:
     * @param key:
     * @param objectJsonObject:
     * @param resultJsonObject:
     */
    public void saasAnalysisLinkBusinessMulti(AnalysisDataDTO analysisDataDTO, String key, JSONObject objectJsonObject, JSONObject resultJsonObject){
        Integer businessType = analysisDataDTO.getBusinessType();
        Integer saasMark = analysisDataDTO.getSaasMark();
        resultJsonObject.put(key, objectJsonObject.get(key));
        if (Objects.equals(saasMark, 1)) {
            if (Objects.equals(businessType, XbbRefTypeEnum.SALES_OPPORTUNITY.getCode())) {
                if (Objects.equals(key, SalesOpportunityEnum.LINK_COMPETITOR.getAttr())) {
                    analysisLinkCompetior(analysisDataDTO,objectJsonObject,resultJsonObject,key);
                }
            }
        }
    }
}
